package com.sinosoft.dsp.system.to.attribute;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;

import com.sinosoft.dsp.system.core.exception.SinoFileException;
import com.sinosoft.dsp.system.to.exception.SinoAttributeException;
import com.sinosoft.dsp.system.to.helper.CommonAttributeType;
import com.sinosoft.dsp.system.utils.Const;

/**
 * 对象类型：BLOB，CLOB
 * 
 * @since 1.0 2010-4-22
 * @author 潘巍（Peter Pan）
 * 
 */
public class BlobType extends AbstractType<byte[]> implements Serializable,
		Attribute<byte[]> {

	private static final long serialVersionUID = -8537045500273245151L;

	@Override
	public void setValue(byte[] v) {
		super.setValue(v);
	}

	@Override
	public BlobType cloneAttribute() throws SinoAttributeException {
		BlobType obj = (BlobType) super.cloneAttribute();
		byte[] value = null;
		byte[] ora = obj.getValue();
		if (ora != null) {
			value = new byte[ora.length];
			for (int i = 0; i < ora.length; i++) {
				value[i] = new Byte(ora[i]);
			}
		}
		obj.setValue(value);
		return obj;
	}

	@Override
	public CommonAttributeType getType() {
		return CommonAttributeType.TYPE_BLOB;
	}

	@Override
	public int compare(Attribute<?> attr) throws SinoAttributeException {
		if (attr.getType() != this.getType()) {
			return -1;
		}

		boolean n1 = isNull();
		boolean n2 = true;
		if (attr != null)
			n2 = attr.isNull();

		// null永远最小
		if (n1 && !n2)
			return -1;
		if (!n1 && n2)
			return 1;
		if (n1 && n2)
			return 0;

		int cmp = 0;

		byte[] b1 = (byte[]) getValue();
		byte[] b2 = (byte[]) attr.getValue();

		int length = b1.length < b2.length ? b1.length : b2.length;

		for (int i = 0; i < length; i++) {
			cmp = b1[i] - b2[i];
			if (cmp != 0) {
				cmp = cmp < 0 ? -1 : 1;
				break;
			}
		}

		cmp = b1.length - b2.length;

		return cmp;
	}

	@Override
	public byte[] readData(DataInputStream inputStream)
			throws SinoFileException {
		try {

			if (inputStream.readBoolean())
				return null;

			int size = inputStream.readInt();
			byte[] buffer = new byte[size];
			inputStream.readFully(buffer);

			return buffer;
		} catch (IOException e) {
			throw new SinoFileException(toString() + " : 无法从输入流中读取值数据", e);
		}
	}

	@Override
	public boolean requiresRealClone() {
		return true;
	}

	@Override
	public void writeData(DataOutputStream outputStream)
			throws SinoFileException, SinoAttributeException {
		try {
			outputStream.writeInt(getValue().length);
			outputStream.write(getValue());
		} catch (ClassCastException e) {
			throw new RuntimeException(toString() + " : 发生数据类型错误 ");
		} catch (IOException e) {
			throw new SinoFileException(toString() + " : 无法从输出流中读取值", e);
		}
	}

	@Override
	public void instantiateFromString(String content)
			throws SinoAttributeException {
		if (!Const.isEmpty(content)) {
			try {
				this.setValue(content.getBytes());
				return;
			} catch (Exception e) {
				throw new SinoAttributeException(
						"通过字符串，为SerializableType属性赋值出现错误：", content);
			}
		}

		this.setValue(new byte[] {});
		return;
	}

	@Override
	public String convertToString() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void instantiateFromObject(Object content)
			throws SinoAttributeException {
		if (content != null) {
			if (content instanceof byte[]) {
				this.setValue((byte[]) content);
			} else {
				throw new SinoAttributeException(
						"通过对象，为SerializableType属性赋值出现错误：", content.toString());
			}
		}
	}

}
